package com.youlu.campus.service.pay.impl;

import com.alibaba.fastjson.JSON;
import com.youlu.campus.base.exception.BusinessException;

import com.youlu.campus.entity.*;
import com.youlu.campus.entity.VO.req.ItemPriceCompute;
import com.youlu.campus.entity.VO.req.ShoppingCartComputeReq;
import com.youlu.campus.entity.VO.res.*;
import com.youlu.campus.service.activity.impl.ActivityPayConfigService;
import com.youlu.campus.service.activity.impl.PlatformOtherActivityService;
import com.youlu.campus.service.ca.CaGroupInfoService;
import com.youlu.campus.service.ca.CaInfoMapppingService;
import com.youlu.campus.service.ca.CaInfoService;
import com.youlu.campus.service.cache.CacheCaGroupInfoService;
import com.youlu.campus.service.cache.CachePayConfigService;
import com.youlu.campus.service.pay.PayCategoryConfigService;
import com.youlu.campus.service.pay.UserPurchaseCaService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserPurchaseCaServiceImpl implements UserPurchaseCaService {
    @Resource(name = "masterMongoTemplate")
    private MongoTemplate mongoTemplate;
    @Autowired
    private PayCategoryConfigService payCategoryConfigService;
    @Autowired
    private CaInfoService caInfoService;
    @Autowired
    private CaGroupInfoService caGroupInfoService;
    @Lazy
    @Autowired
    private ActivityPayConfigService payConfigPageService;
    @Lazy
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Lazy
    @Autowired
    private PlatformOtherActivityService platformOtherActivityService;
    @Lazy
    @Autowired
    private CacheCaGroupInfoService cacheCaGroupInfoService;
    @Lazy
    @Autowired
    private CaInfoMapppingService caInfoMapppingService;
    @Lazy
    @Autowired
    private CachePayConfigService cachePayConfigService;

    /**
     * 用户购买商品缓存信息
     */
    private String itemBuyPrefixKey = "com.luyou.item.buy.aid:%s.:uid:%s";
    /**
     * 用户购买商品分类缓存信息
     */
    private String categoryBuyPrefixKey = "com.luyou.category.buy.aid:%s.:uid:%s";

    private String userCaGroupIdsPrefixKey = "com.luyou.user.groupIds.aid:%s.uid:%s";
    private String userCaLevelsPrefixKey = "com.luyou.user.ca.levels.aid:%s.uid:%s";
    private String defaultCategoryPrefixKey = "com.luyou.activity.default.cate:aid:%s:uid:%s";

    @Override
    public ItemCategoryV2Res getItems(String activityId, String categoryId, UserPO userPO) {
        String userId = userPO.getId();
        log.info(":>>> 开始获取商品列表:{},{},{},{}", activityId, categoryId, userId, userPO.getMobile());
        PayCategoryConfig config = payCategoryConfigService.findByCategoryId(categoryId, activityId);
        if (Objects.isNull(config)) {
            log.error(":>>> 活动:{},下商品售卖配置不存在:{}", activityId, categoryId);
            throw new BusinessException("商品售卖配置不存在,请联系在线客服");
        }
        CaGroupInfo caGroupInfo = caGroupInfoService.findOne(config.getCaGroupId());
        ActivityUserRecord activityUserRecord = null;
        try {
            activityUserRecord = platformOtherActivityService.findByOpenidOrMoble(activityId, userPO.getOpenId(),
                    userPO.getMobile(), caGroupInfo.getTaskBizType());
        } catch (Exception e) {
            log.error(":>>> 获取领取错误:{}", e);
        }
        List<CaInfo> todo = new ArrayList<>();
        if (Objects.nonNull(activityUserRecord)) {
            Query query = new Query();
            query.addCriteria(Criteria.where("caGroupInfoId").is(config.getCaGroupId()));
            query.addCriteria(Criteria.where("activityId").is(activityId));
            query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
            if (Objects.nonNull(activityUserRecord) && !"item".equals(config.getType())) {
                query.addCriteria(Criteria.where("level").is(activityUserRecord.getCaLevel()));
            }
            Sort sort = Sort.by(Sort.Direction.DESC, "priority");
            query.with(sort);
            List<CaInfo> items = caInfoService.findWithQuery(query);
            String key = String.format(itemBuyPrefixKey, activityId, userId);
            /**
             * 领取状态,
             * todo:待领取
             * done:已领取
             * expired:已过期
             * disabled:不可领取
             *
             */

            HashMap<String, CaInfo> caMap = new HashMap<>();
            for (CaInfo c1 : items) {
                caMap.put(c1.getId(), c1);
            }
            for (CaInfo c : items) {
                Boolean b = redisTemplate.opsForHash().hasKey(key, c.getId());
                if (Boolean.TRUE.equals(b)) {
                    if (Boolean.TRUE.equals(c.getCombinedCommodity())) {
                        log.info(":>>> 商品是组合装,已经购买:{}", c.getId());
                        List<CaInfoMappping> childs = caInfoMapppingService.findByParentId(c.getId());
                        if (CollectionUtils.isNotEmpty(childs)) {
                            for (CaInfoMappping child : childs) {
                                if (StringUtils.isNotBlank(child.getCaInfoId()) && caMap.containsKey(child.getCaInfoId())) {
                                    caMap.get(child.getCaInfoId()).setClaimStatus("disabled");
                                }
                            }
                        }
                    } else {
                        log.info(":>>> 商品不是组合装,已经购买:{}", c.getId());
                        if (1 == c.getItemType()) {
                            List<CaInfoMappping> mapppings = caInfoMapppingService.findByCaInfoId(c.getId());
                            for (CaInfoMappping cm : mapppings) {
                                if (StringUtils.isNotBlank(cm.getParentId())) {
                                    CaInfo p = caMap.get(cm.getParentId());
                                    if (Objects.nonNull(p)) {
                                        p.setClaimStatus("disabled");
                                        caMap.put(cm.getParentId(), p);
                                    }
                                }
                            }
                        }

                    }
                    if (2 != c.getItemType()) {
                        caMap.get(c.getId()).setClaimStatus("disabled");
//                    c.setClaimStatus("disabled");
                    } else {
                        caMap.get(c.getId()).setClaimStatus("done");
//                    c.setClaimStatus("todo");
                    }
                } else {
                    caMap.get(c.getId()).setClaimStatus("todo");
//                c.setClaimStatus("todo");
                }
            }
            // TODO:排序需要处理
//        for (String s : caMap.keySet()) {
//            todo.add(caMap.get(s));
//        }
            for (CaInfo c1 : items) {
                CaInfo t = caMap.get(c1.getId());
                if (Objects.nonNull(t)) {
                    todo.add(t);
                }
            }
        }
        ItemCategoryV2Res res = new ItemCategoryV2Res();
        res.setItems(todo);
        res.setCategoryId(categoryId);
        res.setSellingTitle(caGroupInfo.getSellingTitle());
        res.setBuyMultiCA(caGroupInfo.getBuyMultiCA());
        res.setCaGroupId(caGroupInfo.getId());
        PayConfigPage payConfigPage = payConfigPageService.findByActivityId(activityId);
        res.setStartTime(payConfigPage.getStartTime());
        res.setEndTime(payConfigPage.getEndTime());
        log.info(":>>> 活动:{},类型:{}的商品主页信息为:{}", activityId, categoryId, res.getItems().size());
        return res;
    }

    @Override
    public UserItemBuyV2Res getIndexInfo(UserPO userPO, String activityId) {
        String userId = userPO.getId();
        log.info(":>>> 开始获取用户商品购买主页信息userId:{},activityId:{}", userId, activityId);
        PayConfigPage payConfigPage = payConfigPageService.findByActivityId(activityId);
        if (Objects.isNull(payConfigPage)) {
            log.error(":>>> 活动:{},下商品售卖配置不存在", activityId);
            throw new BusinessException("商品售卖配置不存在,请联系在线客服");
        }
        Date date = new Date();
        UserItemBuyV2Res res = new UserItemBuyV2Res();
        res.setActivityId(activityId);
        res.setOpenCountDown(payConfigPage.getShowCountDown());
        res.setPromotion(payConfigPage.getPromotion());
        res.setStartTime(payConfigPage.getStartTime());
        res.setEndTime(payConfigPage.getEndTime());
        List<PayCategoryConfig> configs = payCategoryConfigService.findByActivityId(activityId);
        if (CollectionUtils.isEmpty(configs)) {
            return res;
        }
        String key = this.getCategoryBuyRecordKey(activityId, userId);
        List<PayCategoryConfig> todo = new ArrayList<>();
        List<String> groupIds = this.getUserCaGroupId(activityId, userId, userPO.getMobile(), userPO.getOpenId());
        for (PayCategoryConfig p1 : configs) {
            if (StringUtils.isNotBlank(p1.getCaGroupId())) {
                if (groupIds.contains(p1.getCaGroupId())) {
                    todo.add(p1);
                }
            }
        }
        for (PayCategoryConfig p : todo) {
            ItemBuyDetail detail = new ItemBuyDetail();
            detail.setName(p.getName());
            detail.setButtonName(p.getButtonName());
            detail.setImageUrl(p.getMainImageUrl());
            detail.setMarketingClaim(p.getMarketingClaim());
            detail.setCategoryId(p.getId());
            detail.setCaGroupId(p.getCaGroupId());
            // 控制按钮的状态
            if (Objects.nonNull(payConfigPage) && Objects.nonNull(payConfigPage.getEndTime())) {
                if (payConfigPage.getEndTime().before(date)) {
                    detail.setStatus("closed");
                } else {
                    Boolean exist = redisTemplate.opsForHash().hasKey(key, p.getId());
                    log.info(":>>> 用户分类是否购买标记:{}.{}", key, p.getId());
                    if (Boolean.TRUE.equals(exist)) {
                        detail.setStatus("purchased");
                    } else {
                        detail.setStatus("to-purchase");
                    }
                }
            }
            res.getItemCategories().add(detail);
        }
        return res;
    }

    @Override
    public ItemCategoryV2Res getItemCategory(String type, String activityId) {
        log.info(":>>> 开始获取商品分类详情:{}", type, activityId);
        PayCategoryConfig config = payCategoryConfigService.findByType(type, activityId);
        if (Objects.isNull(config)) {
            log.error(":>>> 活动:{},下商品售卖配置不存在:{}", activityId, type);
            throw new BusinessException("商品售卖配置不存在,请联系在线客服");
        }
        PayConfigPage payConfigPage = payConfigPageService.findByActivityId(activityId);
        Query query = new Query();
        query.addCriteria(Criteria.where("caGroupInfoId").is(config.getCaGroupId()));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        Sort sort = Sort.by(Sort.Direction.DESC, "priority");
        query.with(sort);
        List<CaInfo> items = caInfoService.findWithQuery(query);
        ItemCategoryV2Res res = new ItemCategoryV2Res();
        res.setItems(items);
        CaGroupInfo caGroupInfo = caGroupInfoService.findOne(config.getCaGroupId());
        res.setSellingTitle(caGroupInfo.getSellingTitle());
        res.setCategoryId(config.getId());
        res.setStartTime(payConfigPage.getStartTime());
        res.setEndTime(payConfigPage.getEndTime());
        log.info(":>>> 活动:{},类型:{}的商品主页信息为:{}", activityId, type, res.getItems().size());
        return res;
    }

    @Override
    public List<FrontCategory> getFrontCategories(String activityId, UserPO userPO) {
        log.info(":>>> 开始获取前端类目:{}", activityId);
        List<PayCategoryConfig> datas = payCategoryConfigService.findByActivityId(activityId);
        if (CollectionUtils.isEmpty(datas)) {
            return new ArrayList<>();
        }
        List<String> groupIds = this.getUserCaGroupId(activityId, userPO.getId(), userPO.getMobile(), userPO.getOpenId());
        List<FrontCategory> res = new ArrayList<>();
        for (PayCategoryConfig p : datas) {
            FrontCategory f = new FrontCategory();
            f.setName(p.getName());
            f.setCaGroupId(p.getCaGroupId());
            f.setCategoryId(p.getId());
            if (StringUtils.isNotBlank(p.getCaGroupId())) {
                CaGroupInfo group = cacheCaGroupInfoService.findById(p.getCaGroupId());
                if (groupIds.contains(p.getCaGroupId())) {
                    f.setTaskBizType(group.getTaskBizType());
                    res.add(f);
                }
            }
        }
        return res;
    }

    @Override
    public ShoppingCartComputeRes computeCartFee(ShoppingCartComputeReq r) {
        log.info(":>>> 开始计算购物车价格:{}", JSON.toJSON(r));
        ShoppingCartComputeRes res = new ShoppingCartComputeRes();
        Integer num = 0;
        Integer totalFee = 0;
        Integer discountFee = 0;
        for (ItemPriceCompute i : r.getItems()) {
            if (StringUtils.isBlank(i.getItemId())) {
                continue;
            }
            CaInfo caInfo = caInfoService.findOne(i.getItemId());
            if (Objects.nonNull(caInfo)) {
                caInfo.setNum(i.getNum());
                res.getItems().add(caInfo);
            }
            num = num + i.getNum();
            totalFee = totalFee + caInfo.getPrice() * i.getNum();
            discountFee = discountFee + caInfo.getDiscountFee() * i.getNum();
        }
        res.setTotalFe(totalFee);
        res.setDiscountFee(discountFee);
        res.setNum(num);
        return res;
    }

    @Override
    public void updateItemBuyRecord(String orderNo, Date date) {
        log.info(":>>> 开始更新订单商品的购买记录:{},{}", orderNo, date);
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        OrderInfo orderInfo = this.mongoTemplate.findOne(query, OrderInfo.class);
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 更新商品购买状态，订单不存在:{}", orderNo);
            return;
        }
        Query querySub = new Query();
        querySub.addCriteria(Criteria.where("orderNo").is(orderNo));
        List<OOrderInfo> subs = this.mongoTemplate.find(querySub, OOrderInfo.class);
        if (CollectionUtils.isEmpty(subs)) {
            log.error(":>>> 订单的子订单不存在:{}", orderNo);
            return;
        }
        String key = getItemBuyRecordKey(orderInfo.getActivityId(), orderInfo.getAccountInfoId());
        for (OOrderInfo s : subs) {
            redisTemplate.opsForHash().putIfAbsent(key, s.getItemInfoId(), Boolean.TRUE);
        }
        redisTemplate.expire(key, 30, TimeUnit.DAYS);
    }

    @Override
    public void deleteItemBuyRecord(String activityId, String userId, String itemId) {
        log.error(":>>> 开始删除商品的购买记录:{},{},{}", activityId, userId, itemId);
        try {
            String key = getItemBuyRecordKey(activityId, userId);
            redisTemplate.opsForHash().delete(key, itemId);
        } catch (Exception e) {
            log.info(":>>> 删除用户购买记录错误:{}", e);
        }
    }

    @Async
    @Override
    public void updateCategoryBuyRecord(String orderNo, Date date) {
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        OrderInfo orderInfo = this.mongoTemplate.findOne(query, OrderInfo.class);
        if (Objects.isNull(orderInfo)) {
            log.error(":>>> 更新商品分类购买记录，订单不存在:{}", orderNo);
            return;
        }
        String key = this.getCategoryBuyRecordKey(orderInfo.getActivityId(), orderInfo.getAccountInfoId());
        List<OOrderInfo> subs = this.mongoTemplate.find(query, OOrderInfo.class);
        for (OOrderInfo s : subs) {
            List<String> cids = this.getItemCategoryId(s.getItemInfoId());
            for (String cid : cids) {
                redisTemplate.opsForHash().putIfAbsent(key, cid, "1");
            }
        }
        redisTemplate.expire(key, 30, TimeUnit.DAYS);

    }

    @Override
    public void deleteCategoryBuyRecord(String activityId, String userId, String itemId) {
        List<String> cids = this.getItemCategoryId(itemId);
        if (CollectionUtils.isEmpty(cids)) {
            return;
        }
        String key = this.getCategoryBuyRecordKey(activityId, userId);
        for (String cid : cids) {
            redisTemplate.opsForHash().delete(key, cid);
        }
    }

    @Override
    public List<CaInfo> getShoppingCartItems(String activityId, UserPO userPO) {
        log.info(":>>> 开始获取购物车商品aid:{},openId:{},mobile:{}", activityId, userPO.getOpenId(), userPO.getMobile());
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("checked").is(Boolean.TRUE));
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        List<String> groupIds = this.getUserCaGroupId(activityId, userPO.getId(), userPO.getMobile(),
                userPO.getOpenId());
        List<CaInfo> items = mongoTemplate.find(query, CaInfo.class);
        List<CaInfo> todos = new ArrayList<>();
        List<PayCategoryConfig> defaultCates = this.getDefaultCategory(activityId, userPO.getId(), groupIds);
        HashMap<String, String> defaultCatesMap = new HashMap<>();
        PayConfigPage payConfigPage = cachePayConfigService.findByActivityId(activityId);
        int counter = 0;
        for (PayCategoryConfig pc : defaultCates) {
            if (counter >= payConfigPage.getChoicedCateNum()) {
                break;
            }
            defaultCatesMap.put(pc.getCaGroupId(), pc.getId());
            counter++;
        }
        log.info(":>>> 活动用户默认勾选分类:{},{},{}", activityId, userPO.getId(),
                JSON.toJSON(defaultCatesMap));
        String key = this.getItemBuyRecordKey(activityId, userPO.getId());
        List<String> levels = this.getUserCaLevels(activityId, userPO.getId(), userPO.getMobile(), userPO.getOpenId());
        log.info(":>>> 活动用户的证书序列集合和等级集合:{},{},{},{},gids:{},levels:{}", activityId,
                userPO.getId(), userPO.getOpenId(), userPO.getMobile(),
                JSON.toJSON(groupIds), JSON.toJSON(levels));
        for (CaInfo c : items) {
            if (StringUtils.isBlank(c.getCaGroupInfoId())) {
                continue;
            }
            if (!groupIds.contains(c.getCaGroupInfoId())) {
                log.error(":>>> 商品的证书序列不在可以购买序列中:{},{}", c.getId(), c.getCaGroupInfoId());
                continue;
            }
            CaGroupInfo groupInfo = cacheCaGroupInfoService.findById(c.getCaGroupInfoId());
            if (Objects.isNull(groupInfo)) {
                continue;
            }
            Boolean b = redisTemplate.opsForHash().hasKey(key, c.getId());
            log.info(":>>> 商品是否已购买:{},{},等级是否包含:{}", c.getId(), b, levels.contains(c.getLevel()));
            if (Boolean.FALSE.equals(b)) {
                if (levels.contains(c.getLevel())) {
                    if (defaultCatesMap.containsKey(c.getCaGroupInfoId()) && Boolean.TRUE.equals(c.getChecked())) {
                        c.setChecked(true);
                        todos.add(c);
                    }

                }
            }
        }
        log.info(":>>> 活动用户购物车商品数量:{},{},{}", activityId, userPO.getId(),
                todos == null ? 0 : todos.size());
        return todos;
    }

    @Override
    public String getItemTaskBizType(CaInfo c) {
        log.info(":>>> 开始获取商品的taskBizType:{}", c == null ? null : c.getId());
        if (StringUtils.isBlank(c.getCaGroupInfoId())) {
            return "";
        }
        CaGroupInfo g = cacheCaGroupInfoService.findById(c.getCaGroupInfoId());
        if (Objects.isNull(g)) {
            return "";
        }
        return g.getTaskBizType();
    }

    @Override
    public List<String> getUserCaGroupId(String aid, String userId, String mobile, String openId) {
        log.info(":>>> 开始获取用户的证书序列ID列表,aid:{},userId:{},mobile:{},openId:{}", aid
                , userId, mobile, openId);
        String key = this.getuserCaGroupIdsKey(aid, userId);
        Object v = redisTemplate.opsForValue().get(key);
        if (Objects.nonNull(v)) {
            return JSON.parseArray((String) v, String.class);
        }
        List<ActivityUserRecord> records = platformOtherActivityService.findByOpenidOrMoble(aid, openId, mobile);
        if (CollectionUtils.isNotEmpty(records)) {
            List<String> tasKBizTypes = new ArrayList<>();
            for (ActivityUserRecord a : records) {
                if (StringUtils.isNotBlank(a.getTaskBizType())) {
                    if (!tasKBizTypes.contains(a.getTaskBizType())) {
                        tasKBizTypes.add(a.getTaskBizType());
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(tasKBizTypes)) {
                Query query = new Query();
                query.addCriteria(Criteria.where("taskBizType").in(tasKBizTypes));
                query.addCriteria(Criteria.where("activityId").is(aid));
                List<CaGroupInfo> gs = mongoTemplate.find(query, CaGroupInfo.class);
                List<String> gids = new ArrayList<>();
                for (CaGroupInfo g : gs) {
                    if (!gids.contains(g.getId())) {
                        gids.add(g.getId());
                    }
                }
                redisTemplate.opsForValue().set(key, JSON.toJSONString(gids), 5, TimeUnit.MINUTES);
                return gids;
            }

        }
        return new ArrayList<String>();
    }

    @Override
    public List<String> getUserCaLevels(String aid, String userId, String mobile, String openId) {
        log.info(":>>> 开始获取用户的证书等级列表,aid:{},userId:{},mobile:{},openId:{}", aid, userId, mobile, openId);
        Date date = new Date();
        String key = this.getUserCaLevelsKey(aid, userId);
        Object v = redisTemplate.opsForValue().get(key);
        if (Objects.nonNull(v)) {
            log.info(":>>> 缓存:结束获取用户的证书等级列表,aid:{},userId:{},mobile:{},openId:{},耗时:{} 毫秒", aid, userId, mobile,
                    openId, (new Date().getTime() - date.getTime()) / 1000);
            return JSON.parseArray((String) v, String.class);
        }
        List<ActivityUserRecord> records = platformOtherActivityService.findByOpenidOrMoble(aid, openId, mobile);
        List<String> levels = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(records)) {
            for (ActivityUserRecord a : records) {
                if (StringUtils.isNotBlank(a.getCaLevel())) {
                    if (!levels.contains(a.getCaLevel())) {
                        levels.add(a.getCaLevel());
                    }
                }
            }

        }
        redisTemplate.opsForValue().set(key, JSON.toJSONString(levels), 5, TimeUnit.MINUTES);
        log.info(":>>> 数据库:结束获取用户的证书等级列表,aid:{},userId:{},mobile:{},openId:{},证书等级:{},耗时:{} 毫秒", aid, userId, mobile,
                openId, JSON.toJSON(levels), (new Date().getTime() - System.currentTimeMillis()) / 1000);
        return levels;
    }

    @Override
    public List<PayCategoryConfig> getDefaultCategory(String activityId, String userId, List<String> groupIds) {
        log.info(":>>> 开始获取默认分类:{}", activityId);
        String defaultCateKey = getDefaultCategoryPrefixKey(activityId, userId);
        Object v = redisTemplate.opsForValue().get(defaultCateKey);
        if (Objects.nonNull(v)) {
            return JSON.parseArray((String) v, PayCategoryConfig.class);
        }
        PayConfigPage pay = payConfigPageService.findByActivityId(activityId);
        if (Objects.isNull(pay)) {
            log.info(":>>> 活动收款缓存不存在:{}", activityId);
            return new ArrayList<>();
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").is(activityId));
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        if (CollectionUtils.isNotEmpty(groupIds)) {
            query.addCriteria(Criteria.where("caGroupId").in(groupIds));
        }
        Sort sort = Sort.by(Sort.Direction.DESC, "choicePriority");
        query.with(sort);
        query.limit(pay.getChoicedCateNum());
        List<PayCategoryConfig> datas = mongoTemplate.find(query, PayCategoryConfig.class);
        redisTemplate.opsForValue().set(defaultCateKey, JSON.toJSONString(datas), 5, TimeUnit.MINUTES);
        return datas;
    }

    private List<String> getItemCategoryId(String itemId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(itemId));
        CaInfo caInfo = this.mongoTemplate.findOne(query, CaInfo.class);
        if (Objects.isNull(caInfo)) {
            log.error(":>>> 商品不存在:{}", itemId);
            return new ArrayList<>();
        }
        if (StringUtils.isBlank(caInfo.getCaGroupInfoId())) {
            return new ArrayList<>();
        }
        List<PayCategoryConfig> css = payCategoryConfigService.findByCaGroupId(caInfo.getCaGroupInfoId());
        List<String> cids = new ArrayList<>();
        for (PayCategoryConfig p : css) {
            if (!cids.contains(p.getId())) {
                cids.add(p.getId());
            }
        }
        log.info(":>>> 商品对应的分类为:{},{}", itemId, JSON.toJSONString(cids));
        return cids;
    }

    private String getItemBuyRecordKey(String activityId, String userId) {
        return String.format(itemBuyPrefixKey, activityId, userId);
    }

    private String getCategoryBuyRecordKey(String activityId, String userId) {
        return String.format(categoryBuyPrefixKey, activityId, userId);
    }

    private String getuserCaGroupIdsKey(String aid, String uid) {
        return String.format(userCaGroupIdsPrefixKey, aid, uid);
    }

    private String getDefaultCategoryPrefixKey(String aid, String userId) {
        return String.format(defaultCategoryPrefixKey, aid, userId);
    }

    private String getUserCaLevelsKey(String aid, String uid) {
        return String.format(userCaLevelsPrefixKey, aid, uid);
    }

    private boolean existRecord(String activityId, String openId, String mobile, String taskBizType) {
        try {
            ActivityUserRecord ard = platformOtherActivityService.findByOpenidOrMoble(activityId, openId, mobile, taskBizType);
            if (Objects.nonNull(ard)) {
                return true;
            }
        } catch (Exception e) {
            log.error(":>>> 查询用户证书导入记录错误:existRecord");
            return false;
        }
        return false;
    }

}
